package com.redhat.auth.application.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.hibernate.Hibernate;
import org.redhat.auth.security.util.UserCacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dayatang.domain.InstanceFactory;
import com.dayatang.querychannel.service.QueryChannelService;
import com.redhat.auth.application.AccountApplication;
import com.redhat.auth.application.BizSystemApplication;
import com.redhat.auth.domain.Account;
import com.redhat.auth.domain.AccountRepository;
import com.redhat.auth.domain.BizSystem;
import com.redhat.auth.domain.BizSystemBinding;
import com.redhat.auth.domain.BizSystemRepository;
import com.redhat.auth.domain.BizSystemBinding.Status;

/**
 * 
 * @author lingen.liu
 * Account application的实现
 *
 */
@Service(value = "accountApplication")
public class AccountApplicationImpl implements AccountApplication {

	private static QueryChannelService queryChannel;

	public static QueryChannelService getQueryChannel() {
		if (queryChannel == null) {
			queryChannel = InstanceFactory
					.getInstance(QueryChannelService.class);
		}
		return queryChannel;
	}

	public static void setQueryChannel(QueryChannelService queryChannel) {
		AccountApplicationImpl.queryChannel = queryChannel;
	}

	public void update(Account account) {
		account.update();
		UserCacheUtil.removeCacheByUserName(account.getUsername());
	}

	/**
	 * 根据ID返回一个实体
	 */
	public Account getAccount(long id) {
		return Account.get(id);
	}

	/**
	 * 检测同邮件的帐号是否存在
	 */
	public boolean isAccountExistsByEmail(String email) {
		return Account.isEmailExist(email);
	}

	/**
	 * 检测同用户名的帐号是否存在
	 */
	public boolean isAccountExistsByName(String username) {
		return Account.isUsernameExist(username);
	}

	/**
	 * 将一个帐号同多个系统绑定起来
	 * @param accountId  帐号ID
	 * @param systemIds  系统ID
	 * @return
	 */
	public void accountBindSystems(long accountId, String[] systemIds) {
		Account account = Account.get(accountId);
		account.bindingBizSystems(systemIds);
	}

	/**
	 * 将一个帐号同多个系统解除绑定
	 * @param accountId
	 * @param systemIds
	 */
	public void accountUnBindSystem(long accountId, String[] systemIds) {
		Account account = Account.get(accountId);
		account.unBindingBizSystems(systemIds);
	}

	/**
	 * 将一个系统同多个帐号进行绑定
	 * @param systemId
	 * @param accountIds
	 */
	public void systemBindAccount(long systemId, String[] accountIds) {
		BizSystem bizSystem = BizSystem.get(systemId);
		bizSystem.bindingAccounts(accountIds);
	}

	/**
	 * 解除一个系统同多个帐号之间的绑定
	 * @param systemId  要绑定的系统Id
	 * @param accountIds 要绑定的系统
	 */
	public void systemUnBindAccount(long systemId, String[] accountIds) {
		BizSystem bizSystem = BizSystem.get(systemId);
		bizSystem.unBindingAccounts(accountIds);
	}

	/**
	 * 设置一个帐号的绑定的一个系统的状态，可用或不可用
	 */
	public void setBizSystemBindingStatus(long accontId, long systemId,
			Status status) {
		Account account = Account.get(accontId);
		account.setSystemStatus(systemId, status);
	}

	public void add(Account account) {
		account.add();
	}

	public void lock(Account account) {
		account.disabled();
	}

	public void unLock(Account account) {
		account.enabled();
	}

	public Account getAccount(String username) {
		return Account.get(username);
	}

	/**
	 * 根据一个系统ID联动的查询出相应的Account
	 * @param search
	 * @param page
	 * @param pageSize
	 * @return
	 */
	public List<Account> listAccountBySystemId(Account search, int page,
			int pageSize) {
		int firstRow = (page - 1) * pageSize;
		List<Account> accounts = new ArrayList();

		if (search != null)
			accounts = getQueryChannel()
					.queryResult(
							"from Account a join a.bizSystemBindings s where a.username like ? and a.realName like ? and  s.bizSystem = "
									+ search.getId(),
							new Object[] {
									search.getUsername() == null ? "%" : search
											.getUsername()
											+ "%",
									search.getRealName() == null ? "%" : search
											.getRealName()
											+ "%" }, firstRow, pageSize);
		return accounts;
	}

	/**
	 * 获取一个系统，查询出所有未包含此系统的Account
	 * @param search
	 * @param page
	 * @param pageSize
	 * @return
	 */
	public List<Account> listAccountNotContainsSystemId(Account search,
			int page, int pageSize) {
		int firstRow = (page - 1) * pageSize;
		List<Account> accounts = new ArrayList();
		if (search != null)
			accounts = getQueryChannel()
					.queryResult(
							"from Account ac where ac.username like ? and ac.realName like ? and ac.id not in (select a.id from Account a join a.bizSystemBindings s where s.bizSystem = "
									+ search.getId() + ")",
							new Object[] {
									search.getUsername() == null ? "%" : search
											.getUsername()
											+ "%",
									search.getRealName() == null ? "%" : search
											.getRealName()
											+ "%" }, firstRow, pageSize);
		return accounts;
	}

	/**
	 * 传入accountId时，返回所有此ID未绑定的BizSystem
	 */
	public List<BizSystem> listBizSystemNotBindingAccount(Account search,
			int page, int pageSize) {
		int firstRow = (page - 1) * pageSize;
		List<BizSystem> bizSystems = new ArrayList();
		List<Long> existsbizSystems = new ArrayList();

		if (search == null)
			return bizSystems;
		else {
			Account account = getAccount(search.getId());

			Set<BizSystemBinding> bizSystemBindings = account
					.getBizSystemBindings();

			for (BizSystemBinding bizSystemBinding : bizSystemBindings) {
				BizSystem bizSystem = bizSystemBinding.getBizSystem();
				existsbizSystems.add(bizSystem.getId());
			}

			if (existsbizSystems.size() == 0) {
				bizSystems = getQueryChannel().queryResult("from BizSystem ",
						new Object[] {}, firstRow, pageSize);
			} else {
				//组装出所有已绑定的systemId
				StringBuffer systemValue = new StringBuffer();
				systemValue.append("(");
				for (int i = 0; i < existsbizSystems.size(); i++) {
					if (i == existsbizSystems.size() - 1) {
						systemValue.append(existsbizSystems.get(i) + ")");
					} else {
						systemValue.append(existsbizSystems.get(i) + ",");
					}
				}

				bizSystems = getQueryChannel().queryResult(
						"from BizSystem s where s.id not in "
								+ systemValue.toString(), new Object[] {},
						firstRow, pageSize);
			}
		}
		return bizSystems;
	}

	/**
	 * 查出所有的accounts
	 * @param search
	 * @param page
	 * @param pageSize
	 * @return
	 */
	public List<Account> listAcounts(Account search, int page, int pageSize) {
		int firstRow = (page - 1) * pageSize;
		List<Account> accounts = null;
		if (search == null)
			accounts = getQueryChannel().queryResult("from Account",
					new Object[] {}, firstRow, pageSize);
		else {
			accounts = getQueryChannel()
					.queryResult(
							"from Account a where a.username like ? and a.realName like ?",
							new Object[] {
									search.getUsername() == null ? "%" : search
											.getUsername()
											+ "%",
									search.getRealName() == null ? "%" : search
											.getRealName()
											+ "%" }, firstRow, pageSize);
		}

		return accounts;
	}
}
